home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok59.lha
/
AmokEd_V1.02b
/
txt
/
EdCmd1.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
17KB
|
572 lines
(*************************************************************************
:Program. EdCmd1.mod
:Contents. Commands for AmokEd
:Author. Hartmut Goebel
:Language. Oberon
:Translator. Amiga Oberon Compiler V1.17.1
:Imports. SupLib (Hartmut Goebel)
:History. V0.2, 29 Dec 1990 Hartmut Goebel [hG]
:History. V1.0, 14 Apr 1991 [hG]
:History. V1.0b 26 Apr 1991 [hG] -Bug in Quit
:History. V1.0c 12 Aug 1991 [hG] changed Quit-mechanism
:Date. 14 Aug 1991 14:37:30
*************************************************************************)
MODULE EdCmd1;
(* $Debug- *)
IMPORT
e: Exec,
d: Dos,
edD: EdDisplay,
edE: EdErrors,
edG: EdGlobalVars,
edK: EdKeyboard,
edL: EdLowLevel,
edM: EdMovement,
eMn: EdMenu,
g: Graphics,
I: Intuition,
ol: OberonLib,
sl: SupLib,
str: Strings,
sys: SYSTEM;
CONST
(* Flags für einzelne Kommandos *)
escImm* = 0; (* unterscheiden ESCIMM - ESC *)
resetToggle* = 0;
setToggle* = 1;
ifElse* = 0;
while* = 1;
rxQuit* = 0; (* beendet auf jeden Fall *)
(* Relationen *)
relLess = 1;
relGreater = 2;
relEqual = 4;
BadConditional = "Bad conditional";
FileHasBeenModified = "*** File has been modified ***";
CantUniconify = "Can't UnIconify";
VAR
SaveTopLine: LONGINT;
SavePos, SaveTopPos: INTEGER;
(* ---------- esc, escimm --------- *)
PROCEDURE EscapeCommLineMode*;
BEGIN
IF edG.commLineMode IN edG.Status THEN
IF edG.LineBufferLen > 0 THEN
DISPOSE(edG.recallBuffer);
edG.recallBuffer := edL.CopyString(sys.ADR(edG.LineBuffer));
END;
EXCL(edG.Status,edG.commLineMode);
edK.ReturnOveride(FALSE);
edG.Text.topLine := SaveTopLine; edG.Text.pos := SavePos;
edG.Text.topPos := SaveTopPos; edD.TextLoad;
g.SetAPen(edG.RPort,0);
g.RectFill(edG.RPort,edD.Col(0),edD.Row(edG.Rows-1)-1,
edG.XBase+edG.XPixs,edG.YBase+edG.YPixs);
edD.TextDisplaySeg(edG.Rows-2,2);
END;
END EscapeCommLineMode;
PROCEDURE doEsc*;
BEGIN
IF edG.commLineMode IN edG.Status THEN
EscapeCommLineMode;
RETURN;
END;
edD.PutBackLine;
edL.WindowTitle;
IF (escImm IN edG.ArgSet) AND (edG.Arg[0] # NIL) THEN
edG.LineBufferLen := str.Length(edG.Arg[0]^);
e.CopyMem(edG.Arg[0]^,edG.LineBuffer,edG.LineBufferLen+1);
ELSE
edG.LineBuffer := ""; edG.LineBufferLen := 0;
END;
INCL(edG.Status,edG.commLineMode);
edK.ReturnOveride(TRUE);
SaveTopLine := edG.Text.topLine;
SavePos := edG.Text.pos; SaveTopPos := edG.Text.topPos;
edG.Text.topLine := edG.Text.line-edG.Rows+1;
edG.Text.pos := edG.LineBufferLen; edG.Text.topPos := 0;
g.SetAPen(edG.RPort,0);
g.RectFill(edG.RPort,edD.Col(0),edD.Row(edG.Rows-1),
edG.XBase+edG.XPixs,edG.YBase+edG.YPixs);
g.SetAPen(edG.RPort,1);
g.Move(edG.RPort,edD.Col(0),edD.Row(edG.Rows-1)-1);
g.Draw(edG.RPort,edG.XBase+edG.XPixs,edD.Row(edG.Rows-1)-1);
edD.TextDisplaySeg(edG.Rows-1,1);
END doEsc;
PROCEDURE doRecall*;
BEGIN
INCL(edG.ArgSet,escImm);
edG.Arg[0] := edG.recallBuffer;
doEsc;
END doRecall;
PROCEDURE doReturn*;
VAR
Buffer: edG.StringPtr;
BEGIN
IF edG.commLineMode IN edG.Status THEN
Buffer := edL.CopyString(sys.ADR(edG.LineBuffer));
EscapeCommLineMode;
IF Buffer # NIL THEN
edG.ExecCmd(Buffer);
DISPOSE(Buffer);
END;
ELSE
edG.Text.pos := 0;
edM.doDownAdd;
END;
END doReturn;
(*-----------------------------------------------------------------------*)
(*
* repeat X command
*
* (if X is not a number it can be abbr. with 2 chars)
*
* X = N -number of repeats
* line -current line # (lines begin at 1)
* lbot -#lines to the bottom, inc. current
* cleft -column # (columns begin at 0)
* (thus is also chars to the left)
* cright-#chars to eol, including current char
* tr -#char positions to get to next tab stop
* tl -#char positions to get to next backtab stop
*)
PROCEDURE doRepeat*;
VAR
n: LONGINT;
Buffer, aux: edG.StringPtr;
len: INTEGER;
BEGIN
edL.BreakReset;
IF edL.StrToInt(edG.Arg[0],n) THEN
IF n = -1 THEN n := MAX(LONGINT); END;
ELSE
CASE CAP(edG.Arg[0][0]) OF
"L": CASE CAP(edG.Arg[0][1]) OF
"I": n := edG.Text.line+1;
|"B": n := edG.Text.numberOfLines-edG.Text.line;
ELSE n := -1; END;
|"C": CASE CAP(edG.Arg[0][1]) OF
"L": n := edG.Text.pos;
|"R": n := edG.LineBufferLen - edG.Text.pos;
ELSE n := -1; END;
|"T": CASE CAP(edG.Arg[0][1]) OF
"R": n := edG.Text.tabStop-(edG.Text.pos MOD edG.Text.tabStop);
|"L": n := edG.Text.pos MOD edG.Text.tabStop;
IF n = 0 THEN n := edG.Text.tabStop; END;
ELSE n := -1; END;
ELSE n := -1; END;
END;
IF n < 0 THEN
edG.Rc := edE.cmdError; edL.Title(BadConditional); RETURN;
END;
Buffer := edL.CopyString(edG.Arg[1]); IF Buffer = NIL THEN RETURN END;
len := str.Length(Buffer^);
aux := edG.Arg[1];
LOOP
edG.ExecCmd(Buffer);
IF (edG.Rc >= edE.AbortLevel) THEN EXIT END;
IF edL.BreakCheck() THEN edG.Rc := edE.AbortLevel; EXIT END;
DEC(n);
IF n = 0 THEN EXIT; END;
e.CopyMem(aux^,Buffer^,len);
END;
DISPOSE(Buffer);
END doRepeat;
(*-----------------------------------------------------------------------*)
PROCEDURE Xor(a{0},b{1}: BOOLEAN): BOOLEAN;
BEGIN
RETURN (a AND ~b) OR (~a AND b);
END Xor;
(*
* IF condition trueaction, IFELSE condition trueaction falseaction
*
* condition: !condition NOT the specified condition.
* # toggle number is SET
* top top of file (on first line)
* bot end of file (on last line)
* left start of line (leftmost column)
* right end of line (nothing but spaces under and to the right)
* modified text has been modified
* insert currently in insert mode
* y[<=>]# cursor is (any OR combo of <,>,=) row # (line numbers start at 1)
* x[<=>]# cursor is (<,>,<=,>=,<>) column # (columns start at 1)
* <> means 'not equal'
*
* cl char under cursor is lower case
* cu char under cursor is upper case
* ca char under cursor is alpha
* cn char under cursor is numeric
* cb char within selected block
* c[<=>]# char under cursor is (combo of <,>,and =) #
*)
PROCEDURE TestCondition(condStr: edG.StringPtr): BOOLEAN;
VAR
not:BOOLEAN;
relation: INTEGER;
value: LONGINT;
PROCEDURE GetRelation():BOOLEAN;
VAR
i: INTEGER;
help: ARRAY 4 OF CHAR;
BEGIN
(* $RangeChk- *)
WHILE (condStr[0] > "A") DO (* Anfang der relation suchen *)
INC(condStr);
END;
i := 0;
WHILE (condStr[i] >= "<") AND (condStr[i] <= ">") DO
INC(i);
END;
(* $RangeChk= *)
IF i>3 THEN
RETURN FALSE; END;
e.CopyMem(condStr^,help,i);
INC(condStr,i);
relation := 0;
REPEAT
DEC(i);
CASE help[i] OF
"<": INC(relation,relLess);
|"=": INC(relation,relEqual);
|">": INC(relation,relGreater);
ELSE
RETURN FALSE;
END;
UNTIL i=0;
IF (relation = 0) OR (relation >= 7) THEN (* zuviel Bedingungen *)
RETURN FALSE; END;
IF relation = relGreater+relLess THEN (* ungleich *)
not := ~not; relation := relEqual; END;
RETURN TRUE;
END GetRelation;
PROCEDURE TestRelationTo(rel{0}: INTEGER;value{1},val{2}:LONGINT): BOOLEAN;
BEGIN
CASE rel OF
relLess: RETURN (val < value);
| relGreater: RETURN (val > value);
| relEqual: RETURN (val = value);
| relLess+relEqual: RETURN (val <= value);
| relGreater+relEqual: RETURN (val >= value);
ELSE
END;
END TestRelationTo;
BEGIN
IF condStr[0] = "!" THEN not := TRUE; INC(condStr);
ELSE not := FALSE; END;
CASE condStr[0] OF
"T": RETURN Xor(not,(edG.Text.line = 0)); |
"B": RETURN Xor(not,(edG.Text.actLinePtr = edG.Text.lineList.tail)); |
"L": RETURN Xor(not,(edG.Text.pos = 0)); |
"R": RETURN Xor(not,(edG.Text.pos=edG.LineBufferLen)); |
"M": RETURN Xor(not,edG.modified IN edG.Text.status); |
"I": INC(condStr);
CASE condStr[0] OF
"0".."9":
IF edL.StrToInt(condStr,value) AND (value<edG.MaxInternToggle) THEN
RETURN Xor(not,SHORT(value) IN edG.Text.toggles); END;
ELSE
RETURN Xor(not,edG.insertMode IN edG.Text.status);
END; |
"C": INC(condStr);
CASE condStr[0] OF
"L": RETURN Xor(not,(edG.LineBuffer[edG.Text.pos] >= "a")
AND (edG.LineBuffer[edG.Text.pos] <= "z")); |
"U": RETURN Xor(not,(edG.LineBuffer[edG.Text.pos] >= "A")
AND (edG.LineBuffer[edG.Text.pos] <= "Z")); |
"A": RETURN Xor(not,edL.IsAscii(edG.LineBuffer[edG.Text.pos])); |
"N": RETURN Xor(not,(edG.LineBuffer[edG.Text.pos] >= "0")
AND (edG.LineBuffer[edG.Text.pos] <= "9")); |
"B": RETURN (Xor(not,(edG.Text = edG.Block.Owner) AND
(edG.Text.line >= edG.Block.SNum) AND
(edG.Text.line <= edG.Block.ENum))); |
ELSE
IF GetRelation() AND edL.StrToInt(condStr,value) THEN
RETURN Xor(not,TestRelationTo(relation,value,
ORD(edG.LineBuffer[edG.Text.pos]))); END;
END; |
"X": IF GetRelation() AND edL.StrToInt(condStr,value) THEN
RETURN Xor(not,TestRelationTo(relation,value,edG.Text.pos+1)); END;|
"Y": IF GetRelation() AND edL.StrToInt(condStr,value) THEN
RETURN Xor(not,TestRelationTo(relation,value,edG.Text.line+1)); END;|
ELSE
IF edL.StrToInt(condStr,value) AND (value < edG.MaxToggle) THEN
value := ol.ModDiv(value,16); (* SIZE(SET) in Bits *);
relation := SHORT(sys.REG(1)); (* value MOD 16 steht in D1 *)
RETURN Xor(not,relation IN edG.Toggles[value]);
END;
END; (* CASE condStr[0] *)
edG.Rc := edE.cmdError;
edL.Title(BadConditional);
RETURN FALSE;
END TestCondition;
PROCEDURE doIf*;
VAR
Buffer, Condition, aux: edG.StringPtr;
len: INTEGER;
While: BOOLEAN; (* wg. edG.ExecCmd() *)
BEGIN
While := while IN edG.ArgSet;
IF While THEN
Buffer := edL.CopyString(edG.Arg[1]); IF Buffer = NIL THEN RETURN END;
len := str.Length(Buffer^);
aux := edG.Arg[1];
ELSE
Buffer := edG.Arg[1]; (* nicht erst kopieren *)
END;
Condition := edG.Arg[0]; str.Upper(Condition^); (* sichern *)
edL.BreakReset;
LOOP
IF TestCondition(Condition) THEN
IF (edG.Rc >= edE.AbortLevel) THEN EXIT END;
IF edL.BreakCheck() THEN edG.Rc := edE.AbortLevel; EXIT END;
edG.ExecCmd(Buffer);
IF NOT While THEN EXIT; END;
ELSIF (ifElse IN edG.ArgSet) AND NOT While THEN
edG.ExecCmd(edG.Arg[2]);
EXIT;
ELSE
EXIT;
END;
e.CopyMem(aux^,Buffer^,len);
END;
IF While THEN DISPOSE(Buffer); END;
END doIf;
(*----------------------------------------------------------------------*)
PROCEDURE doIconify*;
VAR
win: I.WindowPtr;
nw: I.NewWindow;
BEGIN
IF NOT (edG.iconMode IN edG.Text.status) THEN
edD.PutBackLine;
win := edG.Text.window;
nw := edG.StdWindow;
edG.Text.leftEdge := win.leftEdge;
edG.Text.topEdge := win.topEdge;
edG.Text.width := win.width;
edG.Text.height := win.height;
nw.height := 11;
nw.width := 20 + 2*8 + str.Length(edG.Text.name)*8;
nw.leftEdge:= edG.Text.iconLeft;
nw.topEdge := edG.Text.iconTop;
nw.blockPen := -1;
IF edG.modified IN edG.Text.status THEN
nw.blockPen := 3;
(* IF edG.kick20 IN edG.Status THEN END; *)
END;
nw.flags := nw.flags-LONGSET{I.windowSizing,I.windowDepth,I.activate};
IF I.windowActive IN win.flags THEN (* wegen ARexx *)
INCL(nw.flags,I.activate); END;
nw.firstGadget := NIL;
nw.title := sys.ADR(edG.Text.name);
IF edG.Screen # NIL THEN
nw.screen := edG.Screen;
nw.type := I.customScreen;
END;
e.Forbid; (* make sure, there is memory *)
sl.CloseWindowSafely(win);
win := sl.OpenPortWindow(nw,edG.MainPort);
e.Permit;
edG.Text.window := win;
edD.SetWindowParams;
INCL(edG.Text.status,edG.iconMode);
INCL(edG.Status,edG.dontReplyIntuiMsg);
END;
END doIconify;
PROCEDURE unIconify*;
VAR
win,win2: I.WindowPtr;
nw: I.NewWindow;
BEGIN
IF edG.iconMode IN edG.Text.status THEN
win := edG.Text.window;
nw := edG.StdWindow;
edG.Text.iconLeft := win.leftEdge; edG.Text.iconTop := win.topEdge;
nw.leftEdge := edG.Text.leftEdge; nw.width := edG.Text.width;
nw.topEdge := edG.Text.topEdge; nw.height := edG.Text.height;
nw.blockPen := -1;
nw.title := sys.ADR(edG.Text.name);
nw.firstGadget := sys.ADR(edG.Text.propGadget);
IF edG.Screen # NIL THEN
nw.screen := edG.Screen;
nw.type := I.customScreen;
END;
win2 := sl.OpenPortWindow(nw,win.userPort);
IF win2 # NIL THEN
sl.CloseWindowSafely(win);
edG.Text.window := win2;
eMn.MenuStrip(win2);
edG.RPort := win2.rPort;
IF edG.Text.font # NIL THEN g.SetFont(edG.RPort,edG.Text.font); END;
edD.SetWindowParams;
edD.TextLoad;
edD.TextRedisplay;
edL.WindowTitle;
EXCL(edG.Text.status,edG.iconMode);
INCL(edG.Status,edG.dontReplyIntuiMsg);
ELSE
edL.Title(CantUniconify);
edG.Rc := edE.cmdSevere;
END;
END;
END unIconify;
(*-----------------------------------------------------------------------*)
(* $Debug= *)
PROCEDURE HandleQuitFlags*;
BEGIN
IF NOT (edG.macroWithQuit IN edG.Text.status) THEN
EXCL(edG.Text.status,edG.quit);
END;
EXCL(edG.Text.status,edG.macroWithQuit);
END HandleQuitFlags;
PROCEDURE doQuit*;
BEGIN
edD.PutBackLine;
IF NOT (edG.modified IN edG.Text.status) OR (edG.quit IN edG.Text.status)
OR (rxQuit IN edG.ArgSet) THEN
edL.EndEdit;
INCL(edG.Status,edG.dontReplyIntuiMsg);
IF edG.Text=NIL THEN
INCL(edG.Status,edG.quitQuit);
RETURN;
END;
edD.TextLoad;
edD.SwitchEdit(edG.Text);
ELSE
edG.Text.status := edG.Text.status + LONGSET{edG.macroWithQuit,edG.quit};
IF edG.iconMode IN edG.Text.status THEN unIconify; END;
edG.Rc := edE.cmdFailed; edL.Title(FileHasBeenModified);
END;
END doQuit;
(* $Debug- *)
(*-----------------------------------------------------------------------*)
PROCEDURE doMargin*;
VAR
long: LONGINT;
BEGIN
IF edL.StrToInt(edG.Arg[0],long) AND (long < 125) THEN
edG.Text.margin := ABS(SHORT(long));
ELSE
edL.Title(edG.ErrorMarginOver124); edG.Rc := edE.cmdError;
END;
END doMargin;
PROCEDURE doTabstop*;
VAR
long: LONGINT;
BEGIN
IF edL.StrToInt(edG.Arg[0],long) AND (long < edG.MaxLineLength) THEN
edG.Text.tabStop := ABS(SHORT(long));
ELSE
edL.Title(edG.BadArgument); edG.Rc := edE.cmdError;
END;
END doTabstop;
(*-----------------------------------------------------------------------*)
PROCEDURE doToggle*;
VAR
Toggle: POINTER TO LONGSET;
long,set: LONGINT;
Title: ARRAY 20 OF CHAR;
bit: INTEGER;
ok: BOOLEAN;
BEGIN
edG.Rc := edE.cmdError;
str.Upper(edG.Arg[0]^);
ok := TRUE;
Toggle := sys.ADR(edG.Text.status);
IF edG.Arg[0]^ ="WORDWRAP" THEN
Title := "WordWrap"; bit := edG.wordWrap;
ELSIF edG.Arg[0]^ ="INSERTMODE" THEN
Title := "InsertMode"; bit := edG.insertMode;
ELSIF edG.Arg[0]^ ="SAVETABS" THEN
Title := "SaveTabs"; bit := edG.saveTabs;
ELSIF edG.Arg[0]^ ="IGNORECASE" THEN
Title := "IgnoreCase"; bit := edG.ignoreCase;
ELSIF edG.Arg[0]^ ="AUTOINDENT" THEN
Title := "AutoIndent"; bit := edG.autoIndent;
ELSIF edG.Arg[0]^ ="NUMLOCK" THEN
Title := "NumLock"; bit := edG.numLock;
Toggle := sys.ADR(edG.Status);
ELSIF edG.Arg[0][0] = "I" THEN
INC(edG.Arg[0]);
IF edL.StrToInt(edG.Arg[0],long) THEN
bit := SHORT(ABS(long));
IF bit < edG.MaxInternToggle THEN
Title := "Toggle i";
str.Append(Title,edG.Arg[0]^);
Toggle := sys.ADR(edG.Text.toggles);
ELSE
ok := FALSE;
END;
ELSE
ok := FALSE;
END;
ELSIF edL.StrToInt(edG.Arg[0],long) THEN
long := SHORT(ABS(long));
IF long < edG.MaxToggle THEN
set := ol.ModDiv(ABS(long),32); (* SIZE(LONGSET) in Bits *)
bit := SHORT(sys.REG(1)); (* long MOD 32 steht in D1 *)
Toggle := sys.ADR(edG.Toggles[SHORT(set)]);
Title := "Toggle ";
str.Append(Title,edG.Arg[0]^);
ELSE
ok := FALSE;
END;
ELSE
ok := FALSE;
END;
IF NOT ok THEN
edL.Title(edG.BadArgument); edG.Rc := edE.cmdError;
ELSE
IF resetToggle IN edG.ArgSet THEN EXCL(Toggle^,bit);
ELSIF setToggle IN edG.ArgSet THEN INCL(Toggle^,bit);
ELSE Toggle^ := Toggle^ / LONGSET{bit};
END;
IF bit IN Toggle^ THEN str.Append(Title," ON");
ELSE str.Append(Title," OFF");
END;
edL.Title(Title); edG.Rc := edE.cmdValid2; (* Titel nicht ändern *)
END;
END doToggle;
END EdCmd1.